#TODO fix crappy naming
require 'hpricot'
module Hpricot
  module Traverse
    TWO_LINEBREAK_CAUSING_ELEMENTS = [
      "p",
      "h1",
      "h2",
      "h3",
      "h4",
      "h5",
      "h6",
      "ol",
      "ul",
      "pre",
      "address",
      "blockquote",
      "dl",
      "dt",
      "dd",
      "div",
      "fieldset",
      "form",
      "hr",
      "table"
    ]
      
    def html_breaks_only
      Hpricot(self.to_html.gsub(/(<br[ \/]*>|<p[^>]*>|<tr[^>]*>)/i, "\n"))
    end
    
    def two_linebreaks_regex
      "(#{TWO_LINEBREAK_CAUSING_ELEMENTS.join("|")})"
    end
    
    def one_linebreak_empty_regex
      "br|tr"
    end
    
    def one_linebreak_regex
      "li"
    end
    
    def causes_two_linebreaks?
      return false unless self.elem?
      File.basename(self.xpath) =~ /^#{two_linebreaks_regex}[^\/]*$/
    end
    
    def causes_one_linebreak_and_empty?
      return false unless self.elem?
      File.basename(self.xpath) =~ /^#{one_linebreak_empty_regex}[^\/]*$/
    end
    
    def causes_one_linebreak?
      return false unless self.elem?
      File.basename(self.xpath) =~ /^#{one_linebreak_regex}[^\/]*$/
    end
    
    def build_nested_array(elem = nil)
      elem ||= self
      nested_array = []
      elem.children.each do |c|
        if !c.elem? # is plain text
          nested_array << c
        elsif c.causes_two_linebreaks?
          nested_array << [build_nested_array(c)]
        elsif c.causes_one_linebreak_and_empty?
          nested_array << []
        elsif c.causes_one_linebreak?
          nested_array << build_nested_array(c)
        else
          nested_array = nested_array + build_nested_array(c)
        end
      end
      
      nested_array
    end
    
    def nested_array_to_line_breaked(data = nil)
      data ||= build_nested_array(self)
      text = ''
      data.each do |d|
        unless d.is_a? Array
          text << "#{d.to_s.gsub(/\s+/, ' ')}"
        else
          text <<  nested_array_to_line_breaked(d) + "\n"
        end
      end
      text
    end
    
    def inner_text_with_html_breaks
      nested_array_to_line_breaked.strip
    end
    
    
  end
end